#include "pluginssd.h"

#include "../core/core.h"
#include "../core/pluginsmanager.h"
#include "pluginstabledelegate.h"

#include <QDebug>
#include <QTabWidget>
#include <QAbstractTableModel>
#include <QStyledItemDelegate>
#include <QList>
#include <QVector>
#include <QTableView>
#include <QVBoxLayout>
#include <QHeaderView>
#include <QMouseEvent>
#include <QLabel>

class PluginsSD::PluginsTableEntry{
public:
	QString fileName;
	QString title;
	int buttonState;
	int pluginState;
};

class PluginsSD::PluginsTableModel : public QAbstractTableModel {
private:
	QList<PluginsSD::PluginsTableEntry> m_list;

public:
	PluginsTableModel(QObject *parent = 0);
	~PluginsTableModel();

	int rowCount(const QModelIndex &parent) const;
	int columnCount(const QModelIndex &parent) const;

	QVariant data(const QModelIndex &index, int role) const;

	QVariant headerData(int section, Qt::Orientation orientation,
						int role = Qt::DisplayRole) const;

	void fillModel(const QList<PluginsManager::PluginsListEntry> &list );

	bool setData(const QModelIndex &index, const QVariant &value,
				 int role = Qt::EditRole);

	QString getFileName(const QModelIndex &index) const;
	void markAsChoosen(const QModelIndex &index);
};

//definitions
PluginsSD::PluginsTableModel::PluginsTableModel(QObject *parent)
	: QAbstractTableModel(parent)
{

}

PluginsSD::PluginsTableModel::~PluginsTableModel(){

}


bool PluginsSD::PluginsTableModel::setData(const QModelIndex &index,
										   const QVariant &value, int role)
{
	if( index.column() != 2 )
		return QAbstractTableModel::setData( index, value, role );

	if( ( Qt::UserRole + 1) == role ){
		m_list[index.row()].buttonState = value.toInt();
		return true;
	}
	return false;
}

void PluginsSD::PluginsTableModel::
				fillModel(const QList<PluginsManager::PluginsListEntry> &list)
{
	m_list.clear();
	foreach(PluginsManager::PluginsListEntry entry, list){
		PluginsSD::PluginsTableEntry elem;
		elem.buttonState = 0;
		elem.pluginState = entry.isLoaded;
		elem.fileName = entry.fileName;
		elem.title = entry.title;
		m_list.push_back( elem );
	}

	reset();
}

int PluginsSD::PluginsTableModel::rowCount(const QModelIndex &parent) const{
	return m_list.count();
}

int PluginsSD::PluginsTableModel::columnCount(const QModelIndex &parent) const{
	return 3;
}

QVariant PluginsSD::PluginsTableModel::data(const QModelIndex &index,
											int role) const
{
	switch( role ){
	case Qt::DisplayRole:
		if( index.column() == 1 )
			return m_list.at( index.row() ).title;
		break;
	case Qt::UserRole:
			if( index.column() == 0 || index.column() == 2 ){
				return QVariant( m_list.at( index.row() ).pluginState );
			}
			break;
	case (Qt::UserRole + 1):
			if( index.column() == 2){
				return QVariant( m_list.at( index.row() ).buttonState );
			}
			break;
	}

	return QVariant();
}

QVariant PluginsSD::PluginsTableModel::headerData(int section,
												  Qt::Orientation orientation,
												  int role) const
{
	if( Qt::DisplayRole != role )
		return QAbstractTableModel::headerData( section, orientation, role );

	if( Qt::Vertical == orientation){
		return QVariant( QString::number( section ) );
	}

	//for horizontal
	switch(section){
	case 1:
		return tr("Nazwa");
	case 2:
		return tr("Akcja");
	}


	return QVariant();
}

QString PluginsSD::PluginsTableModel::getFileName(
												const QModelIndex &index) const
{
	return m_list.at( index.row() ).fileName;
}

void PluginsSD::PluginsTableModel::markAsChoosen(const QModelIndex &index){
	m_list[index.row()].pluginState = 2;
}

//----------
//----------------------
class PluginsSD::PluginsSDPrivate {
public:
	PluginsSDPrivate();
	~PluginsSDPrivate();

	QTabWidget *m_pTab;
	QTableView *m_pTable;
};

PluginsSD::PluginsSDPrivate::PluginsSDPrivate(){
	m_pTab = NULL;
}

PluginsSD::PluginsSDPrivate::~PluginsSDPrivate(){
	delete m_pTab;
}

//end of d-class part
//------------------------------------------------------------------------------
PluginsSD::PluginsSD() :
	QObject(0),
	d(new PluginsSDPrivate())
{
}

PluginsSD::~PluginsSD(){
	delete d;
}

QString PluginsSD::category() const {
	return tr("Wtyczki");
}

QIcon PluginsSD::categoryIcon() const {
	return QIcon(":/settings/res/preferences-plugin.png");
}

QTabWidget* PluginsSD::createPages(){
	if( d->m_pTab )
		return d->m_pTab;

	d->m_pTab = new QTabWidget();

	QWidget *page = new QWidget(d->m_pTab);

	page->setLayout( new QVBoxLayout(page) );

	QTableView *tv = new QTableView(page);
	d->m_pTable = tv;
	tv->setFocusPolicy(Qt::NoFocus);
	tv->verticalHeader()->hide();
	tv->setSelectionBehavior( QAbstractItemView::SelectRows );
	tv->setSelectionMode( QAbstractItemView::NoSelection );
	tv->setShowGrid( false );
	tv->setAlternatingRowColors( true );
	tv->viewport()->setMouseTracking( true );
	tv->viewport()->installEventFilter( this );


	PluginsTableDelegate *delegate = new PluginsTableDelegate(tv);
	connect( delegate, SIGNAL(needsUpdate(QModelIndex)),
			 tv, SLOT(update(QModelIndex)));
	connect( delegate, SIGNAL(clicked(QModelIndex)),
			 this, SLOT(pluginClicked(QModelIndex)));

	connect( this, SIGNAL(notifyMouseLeave()), delegate, SLOT(mouseLeave()));
	tv->setItemDelegate( delegate );

	PluginsTableModel *model = new PluginsTableModel(tv);
	model->fillModel( Core::instance()->pluginsManager()->pluginsList() );
	tv->setModel( model );


	tv->resizeColumnsToContents();
	tv->resizeRowsToContents();

	tv->horizontalHeader()->setClickable( false );
	tv->horizontalHeader()->setResizeMode( 0, QHeaderView::Fixed );
	tv->horizontalHeader()->setResizeMode( 1, QHeaderView::Stretch);
	tv->horizontalHeader()->setResizeMode( 2, QHeaderView::Fixed );


	page->layout()->addWidget( tv );

	QLabel *label = new QLabel( tr("*wszelkie zmiany będą widoczne po ponownym"
								   " uruchomieniu aplikacji"), page );
	page->layout()->addWidget( label );
	d->m_pTab->addTab( page, tr("Bazy") );



	return d->m_pTab;
}

void PluginsSD::save(){

}

void PluginsSD::reset(){

}

bool PluginsSD::eventFilter(QObject *obj, QEvent *event){
	if( obj == d->m_pTable->viewport() ){
		if( event->type() == QEvent::Leave ){
			emit notifyMouseLeave();
		}
		if(event->type() == QEvent::MouseMove ){
			QModelIndex index = d->m_pTable->indexAt(
									static_cast<QMouseEvent *>(event)->pos());
			if ( !index.isValid() ){
				emit notifyMouseLeave();
			}
		}

	}

	// pass the event on to the parent class
	return QObject::eventFilter(obj, event);

}

void PluginsSD::pluginClicked(const QModelIndex &index){
	QString fileName = dynamic_cast<const PluginsTableModel*>
										(index.model())->getFileName( index );
	const PluginsTableModel *model = dynamic_cast<const PluginsTableModel*>
																(index.model());
	const_cast<PluginsTableModel*>(model)->markAsChoosen( index );
	d->m_pTable->update( index );

	Core::instance()->settings()->setValue( Setting::databaseFileKey,
											fileName );

}
